/*
 * SQLFactoryComponent.h
 *
 * This file is part of the SQLHandler a C++ library to add relational
 * database access to the OPeNDAP Hyrax back-end server.
 * Copyright (C) 2010  Carlo Cancellieri <ccancellieri@hotmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301  USA
 *
 *  Created on: 08/lug/2010
 *      Author: carlo cancellieri
 */

#ifndef SQLTYPEFACTORYCOMPONENT_H_
#define SQLTYPEFACTORYCOMPONENT_H_
#include "connector/SQLSimpleConnector.h"
#include "action/SQLAction.h"

#include <BaseType.h>
/**
 * @brief Factory of libdap::BaseType objects.
 * Inherit from this class to implement a factory of objects.
 * This is called Component since it could not be reused by other
 * driver.
 * Here you have to provide (implementing 'action(...)' a map
 * between the an SQL_TYPE an its corresponding DAP_TYPE.
 * You can do this job implementing all in one function like
 * ODBCTypeFactoryComponent do (static way) or use a
 * SQLDynamicTypeFactory to store multiple instance of this
 * class providing for each class the right action method.
 * <br>An instance of this object will be used by the
 * SQLBuildDAS to build a SQLObjectTypeFactory which is able
 * to store the connector status; it will be used as TypeFactory
 * to produce BaseType(s).
 * <br> Note:
 * This is also a good place to implement a cast function used
 * by the SQLSympleType<> (if you use this one to build objects).
 * @see SQLObjectTypeFactory
 * @see ODBCTypeFactoryComponent
 * @see SQLSympleType
 * @see SQLDynamicTypeFactory
 * @see ODBCPlugin
 */
template <class SQL_TYPE,
			class ODBC_TYPE >
class SQLTypeFactoryComponent:public SQLAction<SQL_TYPE,libdap::BaseType> {
private:
	SQLSimpleConnector<SQL_TYPE,ODBC_TYPE> &connector;
public:
#if __CLONE__==1
	/**
	 * @brief This is the implementation of the
	 * Clone interface.
	 * @return a pointer to a clone of this object
	 */
	virtual SQLAction<SQL_TYPE,libdap::BaseType>* create()throw (std::bad_alloc){
		return this->clone();
	};
#if 0
	/**
	 * NOTE: this should be implemented in the specializing class!
	 * @see ODBCTypeFactoryComponent
	 * @brief This is the implementation of the
	 * Clone interface.
	 * @return a pointer to a clone of this object
	 */
	virtual SQLAction<SQL_TYPE,libdap::BaseType> *clone(){
		return new SQLTypeFactoryComponent<SQL_TYPE,libdap::BaseType>(*this);
	}
#endif
#endif
	/**
	 * @brief return a reference to the connector
	 */
	SQLSimpleConnector<SQL_TYPE,ODBC_TYPE> & getConnector(){
		return connector;
	}

	/**
	 * @brief Constructor
	 * @param c is a reference to a SQLSimpleTypeConnector
	 */
	SQLTypeFactoryComponent(SQLSimpleConnector<SQL_TYPE,ODBC_TYPE> &c):
		SQLAction<SQL_TYPE,libdap::BaseType>(),
		connector(c){};

	/**
	 * @brief Copy constructor
	 * @param t is a reference to a constant instance of this class
	 */
	SQLTypeFactoryComponent(const SQLTypeFactoryComponent<SQL_TYPE,ODBC_TYPE> &t):
		SQLAction<SQL_TYPE,libdap::BaseType>(),
		connector(t.connector){};

	/**
	 * @brief action to implement.
	 * This action represent the method which act as
	 * factory.
	 * @note read comment on top of the class for more details
	 * @param a pointer to the SQL_TYPE parameter generated by
	 * SQLTypeConnector::getType()
	 * @return a BaseType pointer of the right type which is able
	 * to read the next value from the connector (using
	 * SQLTypeConnector::getNext()) and set it to the buffer on
	 * BaseType::read() call.
	 */
	virtual libdap::BaseType * action(SQL_TYPE*)
		throw (SQLInternalError,SQLInternalFatalError)=0;

	/**
	 * @brief dtor
	 */
	virtual ~SQLTypeFactoryComponent(){};
};

#endif /* SQLTYPEFACTORYCOMPONENT_H_ */
